package codegen

import (
	"errors"
	"fmt"
	"os"
	"path"
	"strings"

	"golang.org/x/tools/imports"
)

func WriteFiles(dir, localPrefix, tool string, files map[string]string) error {
	var errs []error
	for file, content := range files {
		if !strings.HasPrefix(file, dir) {
			file = dir + "/" + file
		}

		settings := PrettySettings{
			Tool: tool,
			GoPrettySettings: GoPrettySettings{
				LocalPrefix: localPrefix,
			},
		}
		content, prettyErr := PrettyFile(file, content, settings)
		if prettyErr != nil {
			errs = append(errs, prettyErr)
		}

		if err := os.MkdirAll(path.Dir(file), 0700); err != nil {
			errs = append(errs, err)
		} else if err = os.WriteFile(file, []byte(content), 0600); err != nil {
			errs = append(errs, err)
		}
	}

	return errors.Join(errs...)
}

type GoPrettySettings struct {
	LocalPrefix string
}

type PrettySettings struct {
	Tool string
	GoPrettySettings
}

func PrettyFile(file string, content string, settings PrettySettings) (string, error) {
	if strings.HasSuffix(file, ".go") {
		content = fmt.Sprintf("// Code generated by %s, DO NOT EDIT.\n\n%s", settings.Tool, content)
		imports.LocalPrefix = settings.LocalPrefix
		rawContent, err := imports.Process(file, []byte(content), nil)
		if err == nil {
			content = string(rawContent)
		} else {
			// print an error, but also write the file so debugging the generator isn't a pain.
			fmt.Printf("Error formatting file %s: %s\n", file, err)
			return content, err
		}
	}

	return content, nil
}
